/* waitdemo1.c - 演示父进程如何等待子进程完成  
 */  

#include <stdio.h>      // 标准输入输出头文件，用于 printf 和 perror  
#include <stdlib.h>     // 标准库头文件，用于 exit 和 EXIT_SUCCESS/EXIT_FAILURE  
#include <unistd.h>     // Unix 标准头文件，用于 fork 和 sleep  
#include <sys/types.h>  // 定义 pid_t  
#include <sys/wait.h>   // 提供 wait 函数  

#define DELAY 2      // 子进程休眠时间（秒）  

// 函数声明  
void child_code(int delay);  
void parent_code(pid_t childpid);  

int main()  
{  
    pid_t newpid;    // 用于存储新创建子进程的 PID  

    // 在创建子进程之前，打印当前进程的 PID  
    printf("before: mypid is %d\n", getpid());  

    // 创建新进程  
    newpid = fork();  

    if (newpid == -1) {  
        // fork 调用失败，输出错误信息并退出  
        perror("fork failed");  
        exit(EXIT_FAILURE);  
    }  
    else if (newpid == 0) {  
        // 当前为子进程，执行子进程代码  
        child_code(DELAY);  
    }  
    else {  
        // 当前为父进程，执行父进程代码  
        parent_code(newpid);  
    }  

    return EXIT_SUCCESS;  
}  

/*  
 * 子进程代码：打印信息，休眠一定时间，然后退出  
 */  
void child_code(int delay)  
{  
    printf("child %d here. will sleep for %d seconds\n", getpid(), delay);  
    sleep(delay);  // 子进程休眠  
    printf("child done. about to exit\n");  
    exit(17);      // 以状态码 17 退出  
}  

/*  
 * 父进程代码：等待子进程结束，并打印信息  
 */  
void parent_code(pid_t childpid)  
{  
    int wait_rv;    // wait() 的返回值  

    // 调用 wait() 等待子进程结束  
    wait_rv = wait(NULL);  

    if (wait_rv == -1) {  
        // wait 调用失败，输出错误信息  
        perror("wait failed");  
        exit(EXIT_FAILURE);  
    }  

    // 打印等待结束的信息  
    printf("done waiting for %d. Wait returned: %d\n", childpid, wait_rv);  
}